package com.course.app.transformer;

import com.course.app.api.data.*;
import com.course.domain.model.AgendaWeek;
import com.course.domain.model.CoursePlan;
import com.course.domain.model.CourseWeek;
import com.course.util.DateUtils;
import com.google.common.collect.Lists;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by Justin on 2017/5/30.
 */
public class AgendaTransformer {

    public static AgendaDTO toDTO(int agendaId, CourseDTO courseDTO, ResourceDTO resourceDTO, List<AgendaPlanDTO> planDTOS) {
        AgendaDTO agendaDTO = new AgendaDTO();
        agendaDTO.setId(agendaId);
        agendaDTO.setPlans(planDTOS);
        agendaDTO.setCourse(courseDTO);
        agendaDTO.setResource(resourceDTO);
        return agendaDTO;
    }

    public static List<AgendaPlanDTO> toList(LocalDate beginDate, int weekIdx,
                                             List<CourseWeek> courseWeeks,
                                             List<AgendaWeek> agendaWeeks,
                                             Map<Integer, TaskLearnDTO> learnDTOMap,
                                             Map<Integer, TaskClassDTO> classDTOMap,
                                             Map<Integer, TaskEventDTO> eventDTOMap,
                                             Map<Integer, Integer> classTimeMap) {
        List<AgendaPlanDTO> planDTOS = Lists.newArrayListWithCapacity(7);
        for (int weekDay = 1; weekDay <= 7; weekDay++) {
            AgendaPlanDTO planDTO = new AgendaPlanDTO();
            planDTOS.add(planDTO);
            List<AgendaItemDTO> itemDTOS = Lists.newArrayListWithCapacity(courseWeeks.size());
            planDTO.setDate(toDate(beginDate, weekIdx, weekDay));
            planDTO.setItems(itemDTOS);
            for (CourseWeek courseWeek : courseWeeks) {
                int partIdx = courseWeek.getPartIdx();
                AgendaWeek agendaWeek = agendaWeeks.get(partIdx - 1);
                CoursePlan coursePlan = courseWeek.getPlanByWeekDay(weekDay);
                AgendaItemDTO itemDTO = toItem(partIdx, weekDay, agendaWeek, coursePlan, learnDTOMap, classDTOMap, eventDTOMap, classTimeMap);
                if (itemDTO != null) {
                    itemDTOS.add(itemDTO);
                }
            }
        }
        return planDTOS;

    }

    private static AgendaItemDTO toItem(int partIdx, int weekDay,
                                        AgendaWeek week,
                                        CoursePlan plan,
                                        Map<Integer, TaskLearnDTO> learnDTOMap,
                                        Map<Integer, TaskClassDTO> classDTOMap,
                                        Map<Integer, TaskEventDTO> eventDTOMap,
                                        Map<Integer, Integer> classTimeMap) {
        if (week == null || plan == null) {
            return null;
        }
        int time = week.getByWeekDay(weekDay);
        if (time <= 0) {
            return null;
        }
        AgendaItemDTO itemDTO = new AgendaItemDTO();
        itemDTO.setPart(partIdx);
        itemDTO.setTime(time);
        switch (plan.getTaskType()) {
            case LEARN:
                itemDTO.setTaskLearn(learnDTOMap.get(plan.getTaskId()));
                itemDTO.setType(AgendaItemDTO.Type.LEARN);
                break;
            case CLASS:
                itemDTO.setTaskClass(classDTOMap.get(plan.getTaskId()));
                itemDTO.setType(AgendaItemDTO.Type.CLASS);
                Integer classTime = classTimeMap.get(plan.getId());
                if (classTime != null) {
                    itemDTO.setTime(classTime);
                }
                break;
            case EVENT:
                itemDTO.setTaskEvent(eventDTOMap.get(plan.getTaskId()));
                itemDTO.setType(AgendaItemDTO.Type.EVENT);
                break;
            default:
                itemDTO = null;
        }
        return itemDTO;
    }

    private static Date toDate(LocalDate beginDate, int weekIdx, int weekDay) {
        LocalDateTime dateTime = beginDate
                .plusDays((weekIdx - 1) * 7 + weekDay - 1)
                .atTime(0, 0);
        return DateUtils.toDate(dateTime);
    }
}
